/**
 * 时间转换函数 (将秒数转为 "mm:ss" 格式)
 *
 * @param {number} time - 时间(秒)
 * @returns {string} 格式后的时间字符串
 */
export const transTime = (time: number): string => {
    let minute: number | string = parseInt(String(time / 60))
    let sec: string = Math.round(time % 60) + ''
    const isM0 = ':'
    if (minute === 0) {
        minute = '00'.toString()
    } else if (minute < 10) {
        minute = '0' + minute
    }
    if (sec.length === 1) {
        sec = '0' + sec
    }
    return minute + isM0 + sec
}

export const useMusicPlay = () => {
    // 音频上下文对象
    const audioCtx = useState(() => new Audio())
    // 音频是否正播放
    const playing = useState(() => false)
    // 音频总时长(秒)
    const duration = useState(() => 0)
    // 当前播放的音乐
    const currentId = useState(() => -1)
    // 当前播放时间
    const currentTime = useState(() => 0)
    // 音乐ID映射
    const idToItem = useState(() => new Map())
    // 音乐列表数据
    const musicList = useState<any[]>(() => [])

    const setMusic = (lists: any): void => {
        idToItem.value.clear()
        lists.forEach((item: any, index: number):void => {
            idToItem.value.set(item.id, { ...item, index })
        })
        musicList.value = lists
    }

    /**
     * 开始播放
     */
    const play = (): void => {
        audioCtx.value.play().then((): void => {})
    }

    /**
     * 暂停播放
     */
    const pause = (): void => {
        audioCtx.value.pause()
    }

    /**
     * 音频播放事件处理
     */
    const onPlay = (): void => {
        if (!audioCtx.value.paused) {
            playing.value = true
        }
    }

    /**
     * 音频暂停事件处理
     */
    const onPause = (): void => {
        playing.value = false
    }

    /**
     * 音频错误事件处理
     */
    const onError = (): void => {
        onPause()
    }

    /**
     * 切换播放状态(播放/暂停)
     */
    const togglePlay = (): void => {
        if (!playing.value) {
            play()
        } else {
            pause()
        }
    }

    /**
     * 音频元数据加载完成事件处理
     * 获取音频总时长
     */
    const onLoadedMetadata = (): void => {
        duration.value = audioCtx.value.duration
    }

    /**
     * 音频播放进度更新事件处理
     * 更新当前播放时间
     */
    const onTimeupdate = (): void => {
        currentTime.value = audioCtx.value.currentTime
    }

    /**
     * 设置当前播放时间
     *
     * @param {number|any} time - 时间(秒)
     */
    const setCurrentTime = (time: number | any): void => {
        audioCtx.value.currentTime = time
    }

    /**
     * 设置当前播放音乐ID
     *
     * @param {number} id - 音乐ID
     */
    const setCurrentId = (id: number): void => {
        currentId.value = id
        setTimeout((): void => {
            play()
        })
    }

    /**
     * 设置音频源URL
     */
    const setUrl = (): void => {
        const item = idToItem.value.get(currentId.value)
        if (!item) {
            currentId.value = 0
            pause()
        }
        if (item && audioCtx.value.src !== item.audio_url) {
            audioCtx.value.src = item.audio_url
        }
    }

    /**
     * 播放上一首或下一首音乐
     *
     * @param num - 偏移量（-1=上一首, 1=下一首）
     */
    const prevOrNext = (num: number): void => {
        let index = currentMusic.value.index
        if (index === undefined) {
            index = 0
        }
        let newIndex = index + num
        if (newIndex <= 0) {
            newIndex = 0
        }
        if (newIndex >= musicList.value.length - 1) {
            newIndex = musicList.value.length - 1
        }
        playing.value = false
        const item = musicList.value[newIndex]
        setCurrentId(item.id)
    }

    // 绑定音频事件
    if (!audioCtx.value.onplay) {
        audioCtx.value.onloadedmetadata = onLoadedMetadata
        audioCtx.value.onplay = onPlay
        audioCtx.value.onpause = onPause
        audioCtx.value.ontimeupdate = onTimeupdate
        audioCtx.value.onseeking = onTimeupdate
        audioCtx.value.onended = onPause
        audioCtx.value.onerror = onError
    }

    // 计算格式化后的总时长
    const durationTrans = computed(() => transTime(duration.value))
    // 获取当前播放的音乐项
    const currentMusic = computed(() => idToItem.value.get(currentId.value) || {})
    // 计算格式化后的当前播放时间
    const currentTimeTrans = computed(() => transTime(currentTime.value))

    // 监听当前音乐ID变化
    watch(currentId, (value) => {
        if (value === -1) {
            audioCtx.value.src = ''
            duration.value = 0
        } else {
            setUrl()
        }
    })

    // 监听音乐列表的变化
    watch(musicList, setUrl)

    // 组件卸载前清理操作
    onBeforeUnmount(() => {
        pause()
        onPause()
        duration.value = 0
        audioCtx.value.src = ''
    })

    return {
        audioCtx,
        playing,
        duration,
        musicList,
        currentId,
        currentTime,
        currentMusic,
        durationTrans,
        currentTimeTrans,
        play,
        pause,
        togglePlay,
        prevOrNext,
        setMusic,
        setCurrentId,
        setCurrentTime,
    }
}
